package com.smedi.ismedi.organization.core.port.adapter.persistence.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.ProjectOrganization;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.dto.ProjectOrganizationQuery;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.model.ProjectOrganizationModel;
import com.smedi.ismedi.organization.core.domain.repository.ProjectOrganizationRepository;
import com.smedi.ismedi.organization.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.organization.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.organization.core.port.adapter.persistence.model.ProjectOrganizationEntity;
import com.smedi.ismedi.organization.core.port.adapter.persistence.mybatis.mapper.ProjectOrganizationMapper;
import com.smedi.ismedi.web.starter.exception.LogicException;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.util.List;

@Slf4j
@Repository
@AllArgsConstructor
public class ProjectOrgRepositoryImpl extends ServiceImpl<ProjectOrganizationMapper, ProjectOrganizationEntity> implements ProjectOrganizationRepository, IService<ProjectOrganizationEntity> {
    private DozerUtil dozerUtil;

    private AdapterConverter adapterConverter;

    // 根据组织id查询记录
    @Override
    public ProjectOrganization selectByProjectOrganizationId(Long projectOrganizationId) {
        ProjectOrganizationEntity row = this.getBaseMapper().selectById(projectOrganizationId);
        if (row != null) {
            // 需要考虑软删除这块内容
            return dozerUtil.convertor(row, ProjectOrganization.class);
        } else {
            return null;
        }
    }

    @Override
    public List<ProjectOrganization> queryAll() {
        List<ProjectOrganizationEntity> projectOrganizationEntities = this.getBaseMapper().selectList(null);

        return dozerUtil.convertor(projectOrganizationEntities, ProjectOrganization.class);
    }

    // 新建行政组织数据
    @Override
    public ProjectOrganization doInsert(ProjectOrganization data) {
        ProjectOrganizationEntity ProjectOrganizationEntity = dozerUtil.convertor(data, ProjectOrganizationEntity.class);
        this.getBaseMapper().insert(ProjectOrganizationEntity);
        return dozerUtil.convertor(ProjectOrganizationEntity, ProjectOrganization.class);
    }

    @Override
    public ProjectOrganization doUpdate(ProjectOrganization data) {
        ProjectOrganizationEntity ProjectOrganizationEntity = dozerUtil.convertor(data, ProjectOrganizationEntity.class);
        this.getBaseMapper().updateById(ProjectOrganizationEntity);
        return dozerUtil.convertor(ProjectOrganizationEntity, ProjectOrganization.class);
    }

    @Override
    public void doDelete(ProjectOrganization data) {
        // 判断这条数据是否已经被删除
        ProjectOrganizationEntity row = this.getById(data.getProjectOrganizationId());
        if (row != null) {
            this.getBaseMapper().deleteById(data.getProjectOrganizationId()); // 删除
        } else {
            throw LogicException.raise(CustomError.PROJECT_ORGANIZATION_NOT_EXIST);
        }
    }

    @Override
    public List<ProjectOrganization> selectByParentId(Long projectOrganizationId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.eq("parent_id", projectOrganizationId)
                .orderByAsc("display_order", "id");
        List<ProjectOrganizationEntity> rows = this.getBaseMapper().selectList(wrapper);
        return dozerUtil.convertor(rows, ProjectOrganization.class);
    }

    @Override
    public List<ProjectOrganization> selectAllRoots(Long projectId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("is_root", true)
                .eq("project_id", projectId)
                .orderByAsc("display_order", "id");
        List<ProjectOrganizationEntity> rows = this.getBaseMapper().selectList(wrapper);
        return dozerUtil.convertor(rows, ProjectOrganization.class);
    }

    @Override
    public int selectFullNameCount(String fullName, Long projectOrganizationId, Long projectId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.eq("full_name", fullName)
                .eq("project_id", projectId);
        if (projectOrganizationId != null) {
            wrapper.ne("id", projectOrganizationId);
        }
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public int selectShortNameCount(String shortName, Long projectOrganizationId, Long projectId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.eq("short_name", shortName)
                .eq("project_id", projectId);
        if (projectOrganizationId != null) {
            wrapper.ne("id", projectOrganizationId);
        }
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public int selectOrganizationCodeCount(String organizationCode, Long projectOrganizationId, Long projectId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.eq("organization_code", organizationCode)
                .eq("project_id", projectId);
        if (projectOrganizationId != null) {
            wrapper.ne("id", projectOrganizationId);
        }
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public List<ProjectOrganization> selectAllByFullNameLikeAndProjectId(String fullName, Long projectId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.like("full_name", fullName);
        // 项目id非必填
        if (projectId != null) {
            wrapper.eq("project_id", projectId);
        }
        wrapper.orderByAsc("id");
        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), ProjectOrganization.class);
    }

    @Override
    public List<ProjectOrganization> selectAllByFullNameList(List<String> fullNameList) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.in("full_name", fullNameList);
        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), ProjectOrganization.class);
    }

    @Override
    public List<ProjectOrganization> selectAllByProjectId(Long projectId) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.eq("project_id", projectId).orderByAsc("id");
        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), ProjectOrganization.class);
    }

    @Override
    public List<ProjectOrganization> selectAllByProjectIdAndSpecialTypes(Long projectId, List<String> specialTypes) {
        QueryWrapper<ProjectOrganizationEntity> wrapper = new QueryWrapper();
        wrapper.eq("project_id", projectId);

        if (specialTypes != null && specialTypes.size() > 0) {
            wrapper.in("type", specialTypes);
        }

        wrapper.orderByAsc("id");
        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), ProjectOrganization.class);
    }

    @Override
    public List<ProjectOrganizationModel> getProjectOrganizationList(ProjectOrganizationQuery projectOrganizationQuery) {
        LambdaQueryWrapper<ProjectOrganizationEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(projectOrganizationQuery.getIds()), ProjectOrganizationEntity::getId, projectOrganizationQuery.getIds());
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(projectOrganizationQuery.getProjectIds()), ProjectOrganizationEntity::getProjectId, projectOrganizationQuery.getProjectIds());
        lambdaQueryWrapper.eq(ObjectUtils.isNotNull(projectOrganizationQuery.getProjectId()), ProjectOrganizationEntity::getProjectId, projectOrganizationQuery.getProjectId());
        lambdaQueryWrapper.eq(StringUtils.isNoneBlank(projectOrganizationQuery.getType()), ProjectOrganizationEntity::getType, projectOrganizationQuery.getType());

        List<ProjectOrganizationEntity> projectOrganizationEntities = this.getBaseMapper().selectList(lambdaQueryWrapper);

        return adapterConverter.projectOrganizationEntityToProjectOrganization(projectOrganizationEntities);
    }
}
